using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

using BestHTTP;
using BestHTTP.WebSocket;
using BestHTTP.Cookies;
using pEventBus;
using Google.Protobuf;
using Google.Protobuf.Collections;

using Io.Marsdigital.CommonProtocol.Pb;
using Com.Shinian.FcgProtocol.Pb;
using FCG.cache.proxy_model;
using Network;



namespace Network
{
    public interface ProxyCache
    {
        void blood(RepeatedField<PMModelDTO.Types.PMFieldDTO> data);
        void update(RepeatedField<PMUpdatePackDTO.Types.PMUpdateDTO> data);
    }

    public class ProxyModelUpdateEvent : AbstractSmartObj
    {
        public int eventType;
        public PMUpdatePackDTO.Types.CollectionUpdateWayENUM updateWay;
        public RepeatedField<int> curs = new RepeatedField<int>();
        public object updateObj;
        public object attachData;
        public object Value;
        public object oldValue;

        public override void OnRelease()
        {
            if (curs != null)
            {
                curs.Clear();
            }
            updateObj = null;
            attachData = null;
        }
    }

    public class ProxyModelUpdateListener
    {
        public delegate void ProxyModelEventHandler(ProxyModelUpdateEvent bubbleEvent);
        public ProxyModelEventHandler BubbleEventHandler;

        private List<Delegate> _reserved_callback_list = new List<Delegate>();

        public void Reserve(ProxyModelEventHandler cb)
        {
            if (cb != null && !_reserved_callback_list.Contains((Delegate)cb))
            {
                _reserved_callback_list.Add((Delegate)cb);
            }
        }

        public void Unreserve(ProxyModelEventHandler cb)
        {
            if (_reserved_callback_list.Contains((Delegate)cb))
            {
                _reserved_callback_list.Remove((Delegate)cb);
            }
        }

        public void Bubble(ProxyModelUpdateEvent bubbleEvent)
        {
            if (BubbleEventHandler != null)
            {
                BubbleEventHandler(bubbleEvent);
            }
        }

        public void Clear()
        {
            if (BubbleEventHandler != null)
            {
                Delegate[] handlers = BubbleEventHandler.GetInvocationList();
                for (int ii = 0; ii < handlers.Length; ++ii)
                {
                    if (!_reserved_callback_list.Contains(handlers[ii]))
                    {
                        BubbleEventHandler -= (ProxyModelEventHandler)handlers[ii];
                    }
                }
            }
        }
    }

    public class SharedBuffer : AbstractSmartObj
    {
        public byte[] buffer = new byte[4096];
        public SharedBuffer() { }
        public override void OnRelease() { }
    }


    public partial class Packet : AbstractSmartObj
    {
        public ushort msgID { get; set; }
        public uint sessionUid { get; set; }
        public object userdata { get; set; }

        public Packet() : base() { }

        private SharedBuffer m_data = null;
        private bool m_needbuildSizedData = true;
        private int m_dataLength = 0;
        private byte[] m_sizedData = null;

        public byte[] sizedData
        {
            get
            {
                if (m_needbuildSizedData)
                {
                    m_needbuildSizedData = false;
                    if (m_dataLength > 0)
                    {
                        if (m_sizedData == null || m_sizedData.Length != m_dataLength)
                            m_sizedData = new byte[m_dataLength];

                        Buffer.BlockCopy(m_data.buffer, 0, m_sizedData, 0, m_dataLength);
                    }
                }
                return m_dataLength > 0 ? m_sizedData : null;
            }
        }

        public override void OnRelease()
        {
            if (m_data != null)
            {
                m_data.Release();
                m_data = null;
            }
            m_dataLength = 0;
            userdata = null;
            m_needbuildSizedData = true;
        }
    }

    public interface IProxyModelHandler
    {
        void handlerUpdateMessage(NetMessageO msg);
    }
}
